#ifndef VL_ROOT_PROP__H_
#define VL_ROOT_PROP__H_

#include <ostream>
#include <set>
#include "vl_map_prop.h"

namespace VL {

/**
 * @Author: CimZzz
 * @Date: 2022-10-17 10:50:15
 * 
 * VLP 特性集合
 */
struct VLPFeature {
	// 特性名集合
	std::set<std::string> nameSet;
	// 宏命令指针
	std::unordered_map<std::string, std::string> marcoMap;
};

/**
 * @Author: CimZzz
 * @Date: 2022-06-16 20:09:26
 * 
 * 根属性节点
 * 特殊的 MAP 节点, 同一颗树中只能存在一个 RootProp
 * 
 * VLP: 明文属性文件
 * VLC: 暗文属性文件
 */
class RootProp: public MapProp {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 20:35:59
	 * 
	 * 构造方法
	 */
	explicit RootProp();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 15:19:23
	 * 
	 * 从 VLP 文件中读取
	 * @param file 文件
 	 * @param ignoreError 是否忽略错误
	 * @param feature VLP 特性集合指针
	 * @return 读取成功返回 true
	 */
	bool readFromVLPFile(VLFile& file, bool ignoreError = false, VLPFeature* future = nullptr);


	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 15:18:44
	 * 
	 * 写入 VLC 文件
	 * @param file 文件
	 * @return 写入成功返回 true
	 */
	bool writeToVLCFile(VLFile& file);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-16 15:19:23
	 * 
	 * 从 VLC 文件中读取
	 * @param file 文件
	 * @return 读取成功返回 true
	 */
	bool readFromVLCFile(VLFile& file);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 11:04:46
	 * 
	 * 构建属性打印信息
	 */
	virtual std::string buildPropPrintInfo();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:16:41
	 * 
	 * 打印属性节点信息, 设置前缀
	 * @param prefix 前缀
	 */
	virtual void printWithPrefix(std::string prefix);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-10-24 17:53:27
	 * 
	 * 获取错误信息
	 * 
	 * @return 错误信息
	 */
	std::string getErrorMessage();

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 18:08:22
	 * 
	 * 读取 VLC 属性
	 * @param input 输入流
	 * @param buf 缓冲区
	 * @return 属性对象指针
	 */
	static std::shared_ptr<VLProp> readVLCProp(std::ifstream & input, char * buf);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 17:37:36
	 * 
	 * 写入 VLC 属性
	 * @param output 输出流
	 * @param buf 缓冲区
	 * @param prop 属性指针
	 * @return 写入成功返回 true
	 */
	static bool writeVLCProp(std::ofstream & output, char * buf, VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 18:28:00
	 * 
	 * 获取 VLC 模式下字符串
	 * @param input 输入流
	 * @param buf 缓冲区
	 * @return 字符串指针
	 */
	static std::shared_ptr<std::string> readVLCStr(std::ifstream & input, char * buf);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 18:33:37
	 * 
	 * 获取 VLC 模式下的长度
	 * @param input 输入流
	 * @param buf 缓冲区
	 * @return 长度值
	 */
	static long readVLCLength(std::ifstream & input, char * buf);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 18:10:20
	 * 
	 * 读取指定尺寸的字节
	 * @param input 输入流
	 * @param buf 缓冲区
	 * @param size 字节尺寸
	 * @return 读取成功返回 true
	 */
	static bool readbytes(std::ifstream & input, char * buf, unsigned int size);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 17:29:56
	 * 
	 * 将整数转换为四字节形式
	 * @param number 整数
	 * @param buf 字节缓冲
	 */
	static void itobytes(unsigned int number, char * buf);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 17:32:06
	 * 
	 * 将四字节组装成整数
	 * @param buf 字节缓冲
	 * @return 整数
	 */
	static unsigned int bytestoi(char * buf);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-10-24 17:47:15
	 * 
	 * 错误信息
	 */
	std::string errorMsg;
};

}

#endif // VL_ROOT_PROP__H_
